'''
1、接受tessng向kafka发送的车辆数据,并进行展示


'''
import threading

import carla
import numpy as np
import time

import redis
from carla import Transform, Rotation, Location
from kafka import KafkaConsumer
import json
from pyproj import Proj


vehicle_actors = []
spawed_ids = {}

# 经纬度转xy坐标，在carla中y坐标的值需要取反
rule = Proj("+proj=tmerc +lon_0=121.2092870660126 +lat_0=31.292829882838856 +ellps=WGS84")
# rule = Proj("+proj=tmerc +lon_0=121.20585769414902 +lat_0=31.290823210868965 +ellps=WGS84")




def main():
           
    try:
                     
    #  ======================================跟服务器实现连接=============================================
        client = carla.Client('localhost', 2000)
        client.set_timeout(10.0)

    #  ======================================使用自定义地图=============================================
        world = client.load_world('tongji')

    # =============================天气=================================

        # 控制世界的天气和时间（太阳的位置） 万里无云，没有降雨，太阳的角度为90
        weather = carla.WeatherParameters(
            cloudiness=0.0,  # 0-100  0 是晴朗的天空，100 是完全阴天
            precipitation=0.0,  # 0 表示没有下雨，100 表示大雨
            precipitation_deposits=0.0, # 0 表示道路上没有水坑，100 表示道路完全被雨水覆盖
            wind_intensity=0.0, # 0 表示平静，100 表示强风，风会影响雨向和树叶
            sun_azimuth_angle=0.0, # 太阳方位角，0～360
            sun_altitude_angle=90.0,  # 太阳高度角，90 是中午，-90 是午夜
            fog_density=0.0, # 0～100 表示雾的浓度或厚度，仅影响RGB相机传感器
            fog_distance=0.0, # 雾开始的距离，单位为米
            wetness=0.0, # 0～100 表示道路湿度百分比，仅影响RGB相机传感器
            fog_falloff=0.0, # 雾的密度，0至无穷大，0 表示雾比空气轻，覆盖整个场景，1表示与空气一样，覆盖正常大小的建筑物
            scattering_intensity=0.0, # 控制光线对雾的穿透程度
            mie_scattering_scale=0.0, # 控制光线与花粉或空气等大颗粒的相互作用，导致天气朦胧，光源周围有光晕，0表示无影响
            rayleigh_scattering_scale=0.0331, # 控制光与空气分子等小粒子的相互作用，取决于光波长，导致白天蓝天或晚上红天
            )
        world.set_weather(weather)
        
    # =============================视角坐标=================================
        x = 130
        y = 0
        x, y = rule(121.20322248292439, 31.292553908303493)
        z = 140
        view_angle = Transform(Location(x=x, y=-y, z=z),
                                    Rotation(pitch=-45, yaw = -180, roll=0.000000))
        world.get_spectator().set_transform(view_angle)  # 设置世界视角
        
        # =============================设置车辆=================================
        
        vehicle_trans12 = Transform(Location(x=x, y=-y, z=100),
                                    Rotation(yaw = 347.65-90))
        blueprint_library = world.get_blueprint_library()
        bp1 = blueprint_library.find('vehicle.lincoln.mkz_2017')
        bp1.set_attribute('color', '0, 0, 0')
        # ego_vehicle1 = world.spawn_actor(bp1, vehicle_trans12)
    
    # =============================创建交通管理器对象，并设置仿真的倍数和车辆最大的速度=================================  
    
        traffic_manager = client.get_trafficmanager(8000)
        traffic_manager.set_global_distance_to_leading_vehicle(2.0)
        traffic_manager.global_percentage_speed_difference(40.0)
        
        if True:
            settings = world.get_settings()
            traffic_manager.set_synchronous_mode(True)
            if not settings.synchronous_mode:
                print("开启异步模式")
                synchronous_master = True
                settings.synchronous_mode = False
                settings.fixed_delta_seconds = 0.1
                world.apply_settings(settings)
            else:
                synchronous_master = False

    # =============================创建kafka消费者=================================
        topic = 'targetChannel'
        bootstrap_servers = '106.120.201.126:14576'
        # 创建Kafka消费者实例
        consumer = KafkaConsumer(
            topic,
            bootstrap_servers=bootstrap_servers,
            auto_offset_reset='latest',
            enable_auto_commit=False
        )
    #     target_channel = 'target_channel'
    #     redis_client = redis.StrictRedis(host='10.100.12.58', port=6379, db=0)
    #     pubsub = redis_client.pubsub()
    #     pubsub.subscribe(target_channel)
    #     # 开始监听消息
    #     for message in pubsub.listen():
    #         if message['type'] == 'message':
    #             # 接收到数据，添加处理逻辑
    #             receive_data = message['data'].decode('utf-8')
    #             data_list = json.loads(receive_data)

        while True:
            for message in consumer:
                if message:
                    print("接收到消息：", message)
                    value = message.value.decode('utf-8')
                    json_data = json.loads(value)
                    # print(json_data)
                    participants = json_data['value']['value']
                    errorids = []
                    nowids = []
                    for p in participants:
                        nowids.append(p["id"])
                    #添加交通流
                    for par in participants:

                        x, y = rule(par["longitude"], par["latitude"])



                        print(par["courseAngle"])
                        # vehtype = par['vehicleType']
                        vehtype = 'vehicle.lincoln.mkz_2017'
                        id = par['id']

                        if id not in spawed_ids.keys():
                            trans = Transform(carla.Location(x=x, y=-y, z=15),
                                              carla.Rotation(yaw=par["courseAngle"] - 90))
                            bp1 = world.get_blueprint_library().find(vehtype)
                            try:
                                bp1.set_attribute('color', '0,0,0')
                            except:
                                pass
                            else:
                                pass

                            if vehtype == 'vehicle.lincoln.mkz_2017':
                                batch = [
                                    carla.command.SpawnActor(bp1, trans).then(
                                        carla.command.SetSimulatePhysics(carla.command.FutureActor, False))
                                ]
                                response = client.apply_batch_sync(batch, False)[0]
                                if response.error:
                                    errorids.append(id)
                                else:
                                    spawed_ids[id] = response.actor_id
                            else:
                                batch = [
                                    carla.command.SpawnActor(bp1, trans).then(
                                        carla.command.SetSimulatePhysics(carla.command.FutureActor, False))
                                ]
                                response = client.apply_batch_sync(batch, False)[0]
                                if response.error:
                                    errorids.append(id)
                                else:
                                    spawed_ids[id] = response.actor_id

                        else:
                            trans = Transform(carla.Location(x=x, y=-y, z=15),
                                              carla.Rotation(yaw=par["courseAngle"] - 90))
                            if vehtype == 'vehicle.lincoln.mkz_2017':
                                cid = spawed_ids[id]
                                cactor = world.get_actor(cid)
                                cactor.set_transform(trans)
                            else:
                                carlaid = spawed_ids[id]
                                vehicle = world.get_actor(carlaid)
                                if vehicle is not None:
                                    vehicle.set_transform(trans)
                    print("已有：", len(spawed_ids))

                    destodyed_ids = [id for id in spawed_ids if id not in nowids]
                    for did in destodyed_ids:
                        carlaid = spawed_ids[did]
                        vehicle = world.get_actor(carlaid)

                        if vehicle is not None:
                            vehicle.destroy()
                        del spawed_ids[did]
                    print("更新：", len(nowids), "销毁:", len(destodyed_ids))
                    # print(errorids)

                    print("    Some of the sensor information is missed")
    finally:


        for sensor in spawed_ids:
            sensor.destroy()
        for actor in spawed_ids:
            if actor.is_alive:
                actor.destroy()
        # 停止并清除交通管理器
        # traffic_manager.global_percentage_speed_difference(-100.0)
        # traffic_manager.shutdown()
        # print("All cleaned up!")
        time.sleep(0.1)


     

if __name__ == "__main__":

    try:
        main()
    except KeyboardInterrupt:
        print(' - Exited by user.')
